package main;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JTextField;

import java.awt.Font;
import java.util.ArrayList;

import javax.swing.SwingConstants;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeriesCollection;

import javax.swing.JSlider;

@SuppressWarnings("serial")
public class View extends JFrame{
	private JLayeredPane pnlPolynomial;
	private JTextField txtPolynomial;
	private JTextField txtIterations;	
	private JTextField txtTolerance; // rf
	private JTextField txtEnd; // rf
	private JTextField txtStart; // rf
	private JTextField txtX1; // s
	private JTextField txtX2; // s
	
	// REGULA FALSI
	private JLayeredPane pnlRegulaFalsi;
	private JTable tblRFTable;
	private DefaultTableModel tblRFTableModel;
	private JScrollPane scrRFTable;
	private XYSeriesCollection rfGraphDataset;
	private ChartPanel rfChartPanel;
	private XYPlot rfXYPlot;
	private JScrollPane scrRFGraph;
	private JTextField rfIterationNumber;
	private JSlider rfIterationSlider;
	
	// SECANT
	private JLayeredPane pnlSecant;
	private JTable tblSTable;
	private DefaultTableModel tblSTableModel;
	private JScrollPane scrSTable;
	private XYSeriesCollection sGraphDataset;
	private ChartPanel sChartPanel;
	private XYPlot sXYPlot;
	private JScrollPane scrSGraph;
	private JTextField sIterationNumber;
	private JSlider sIterationSlider;

	// DEFAULT VALUES
	public static final String POLYNOMIAL = "1 3 -2 1 -5 0";
	public static final int ITERATIONS = 15;
	public static final double TOLERANCE = 0.0001;
	public static final double RF_LB = 2;
	public static final double RF_UB = 3;
	public static final double S_X0 = 0;
	public static final double S_X1 = 2;
	
	
	public View(){
		setResizable(false);
		getContentPane().setLayout(null);
		initComponents();
		repaint();
		validate();
	}

	private void initComponents() {
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		this.setSize(new Dimension(1024, 710));
		this.setVisible(true);
		this.setTitle("ADVSTAT - Numerical Methods Simulation");
		this.setLocationRelativeTo(null);
		
		pnlPolynomial = new JLayeredPane();
		pnlPolynomial.setOpaque(true);
		pnlPolynomial.setBorder(new TitledBorder(new LineBorder(null, 1, true),
				"Polynomial", TitledBorder.LEADING,
				TitledBorder.TOP, null, null));
		pnlPolynomial.setBounds(250, 555, 467, 115);
		getContentPane().add(pnlPolynomial);
		pnlPolynomial.setLayout(null);
		
		txtPolynomial = new JTextField(POLYNOMIAL);
		txtPolynomial.setBounds(12, 24, 447, 25);
		pnlPolynomial.add(txtPolynomial);
		txtPolynomial.setHorizontalAlignment(SwingConstants.CENTER);
		txtPolynomial.setFont(new Font("Tahoma", Font.PLAIN, 15));
		txtPolynomial.setColumns(10);
		
		txtIterations = new JTextField(Integer.toString(ITERATIONS));
		txtIterations.setHorizontalAlignment(SwingConstants.RIGHT);
		txtIterations.setFont(new Font("Tahoma", Font.PLAIN, 15));
		txtIterations.setBounds(99, 52, 117, 25);
		pnlPolynomial.add(txtIterations);
		txtIterations.setColumns(10);
		
		txtTolerance = new JTextField(Double.toString(TOLERANCE));
		txtTolerance.setHorizontalAlignment(SwingConstants.RIGHT);
		txtTolerance.setFont(new Font("Tahoma", Font.PLAIN, 15));
		txtTolerance.setColumns(10);
		txtTolerance.setBounds(342, 52, 117, 25);
		pnlPolynomial.add(txtTolerance);
		
		JLabel lblRegulaFalsi = new JLabel("Regula Falsi:");
		lblRegulaFalsi.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblRegulaFalsi.setBounds(12, 79, 117, 25);
		pnlPolynomial.add(lblRegulaFalsi);
		
		JLabel lblSecant = new JLabel("Secant:");
		lblSecant.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblSecant.setBounds(250, 79, 74, 25);
		pnlPolynomial.add(lblSecant);
		
		txtStart = new JTextField(Double.toString(RF_LB));
		txtStart.setHorizontalAlignment(SwingConstants.CENTER);
		txtStart.setFont(new Font("Tahoma", Font.PLAIN, 15));
		txtStart.setColumns(10);
		txtStart.setBounds(99, 79, 44, 25);
		pnlPolynomial.add(txtStart);
		
		txtEnd = new JTextField(Double.toString(RF_UB));
		txtEnd.setHorizontalAlignment(SwingConstants.CENTER);
		txtEnd.setFont(new Font("Tahoma", Font.PLAIN, 15));
		txtEnd.setColumns(10);
		txtEnd.setBounds(172, 79, 44, 25);
		pnlPolynomial.add(txtEnd);
		
		JLabel lblTo = new JLabel("to");
		lblTo.setHorizontalAlignment(SwingConstants.CENTER);
		lblTo.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblTo.setBounds(139, 79, 38, 25);
		pnlPolynomial.add(lblTo);
		
		JLabel lblX = new JLabel("X1");
		lblX.setHorizontalAlignment(SwingConstants.CENTER);
		lblX.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblX.setBounds(307, 79, 38, 25);
		pnlPolynomial.add(lblX);
		
		txtX1 = new JTextField(Double.toString(S_X0));
		txtX1.setHorizontalAlignment(SwingConstants.CENTER);
		txtX1.setFont(new Font("Tahoma", Font.PLAIN, 15));
		txtX1.setColumns(10);
		txtX1.setBounds(342, 79, 44, 25);
		pnlPolynomial.add(txtX1);
		
		txtX2 = new JTextField(Double.toString(S_X1));
		txtX2.setHorizontalAlignment(SwingConstants.CENTER);
		txtX2.setFont(new Font("Tahoma", Font.PLAIN, 15));
		txtX2.setColumns(10);
		txtX2.setBounds(415, 79, 44, 25);
		pnlPolynomial.add(txtX2);
		
		JLabel lblX_1 = new JLabel("X2");
		lblX_1.setHorizontalAlignment(SwingConstants.CENTER);
		lblX_1.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblX_1.setBounds(380, 79, 38, 25);
		pnlPolynomial.add(lblX_1);
		
		JLabel lblIterations = new JLabel("Iterations");
		lblIterations.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblIterations.setBounds(13, 52, 117, 25);
		pnlPolynomial.add(lblIterations);
		
		JLabel lblTolerance = new JLabel("Tolerance");
		lblTolerance.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblTolerance.setBounds(250, 52, 82, 25);
		pnlPolynomial.add(lblTolerance);
		
		// REGULA FALSI
		pnlRegulaFalsi = new JLayeredPane();
		pnlRegulaFalsi.setBorder(new TitledBorder(new LineBorder(null, 1, true),
				"Regula Falsi Method", TitledBorder.LEADING,
				TitledBorder.TOP, null, null));
		pnlRegulaFalsi.setBounds(10, 0, 467, 553);
		getContentPane().add(pnlRegulaFalsi);
		
		scrRFGraph = new JScrollPane();
		scrRFGraph.setBounds(10, 20, 447, 367);
		pnlRegulaFalsi.add(scrRFGraph);
		
		rfGraphDataset = new XYSeriesCollection();
		JFreeChart rfChart= createLineChart(rfGraphDataset, "Regula Falsi");
		rfXYPlot = rfChart.getXYPlot();
		
		rfChartPanel = new ChartPanel(rfChart);
		scrRFGraph.setViewportView(rfChartPanel);
		rfChartPanel.setPreferredSize(new Dimension(430, 350));

		scrRFTable = new JScrollPane();
		scrRFTable.setBounds(10, 420, 445, 120);
		pnlRegulaFalsi.add(scrRFTable);
		
		String [] tableColumnRF = {"i", "X0", "Y0", "X1", "Y1", "X2", "Y2", "tolerance"};
		
		tblRFTable = new JTable();
		tblRFTableModel = new DefaultTableModel();
		tblRFTableModel.setColumnIdentifiers(tableColumnRF);
		tblRFTable.setModel(tblRFTableModel);
		scrRFTable.setViewportView(tblRFTable);
		
		JLabel lblI = new JLabel("i");
		lblI.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblI.setBounds(10, 391, 13, 25);
		pnlRegulaFalsi.add(lblI);
		
		rfIterationNumber = new JTextField("1");
		rfIterationNumber.setHorizontalAlignment(SwingConstants.CENTER);
		rfIterationNumber.setFont(new Font("Tahoma", Font.PLAIN, 15));
		rfIterationNumber.setColumns(10);
		rfIterationNumber.setBounds(425, 391, 30, 25);
		pnlRegulaFalsi.add(rfIterationNumber);
		
		rfIterationSlider = new JSlider(JSlider.HORIZONTAL, 1, ITERATIONS, 1);
		rfIterationSlider.setBounds(20, 391, 403, 23);
		rfIterationSlider.setMinorTickSpacing(1);
		rfIterationSlider.setSnapToTicks(true);
		rfIterationSlider.setPaintTicks(true);
		pnlRegulaFalsi.add(rfIterationSlider);
		
		
		// SECANT
		pnlSecant = new JLayeredPane();
		pnlSecant.setBorder(new TitledBorder(new LineBorder(null, 1, true),
				"Secant Method", TitledBorder.LEADING,
				TitledBorder.TOP, null, null));
		pnlSecant.setBounds(487, 0, 467, 553);
		getContentPane().add(pnlSecant);
		
		scrSGraph = new JScrollPane();
		scrSGraph.setBounds(10, 20, 447, 367);
		pnlSecant.add(scrSGraph);
		
		sGraphDataset = new XYSeriesCollection();
		JFreeChart sChart = createLineChart(sGraphDataset, "Secant");
		sXYPlot = sChart.getXYPlot();
		
		sChartPanel = new ChartPanel(sChart);
		scrSGraph.setViewportView(sChartPanel);
		sChartPanel.setPreferredSize(new Dimension(430, 350));
		
		scrSTable = new JScrollPane();
		scrSTable.setBounds(10, 420, 447, 120);
		pnlSecant.add(scrSTable);
		
		tblSTable = new JTable();
		tblSTableModel = new DefaultTableModel();
		tblSTableModel.setColumnIdentifiers(tableColumnRF);
		tblSTable.setModel(tblSTableModel);		
		scrSTable.setViewportView(tblSTable);
		
		sIterationNumber = new JTextField("1");
		sIterationNumber.setHorizontalAlignment(SwingConstants.CENTER);
		sIterationNumber.setFont(new Font("Tahoma", Font.PLAIN, 15));
		sIterationNumber.setColumns(10);
		sIterationNumber.setBounds(425, 392, 30, 25);
		pnlSecant.add(sIterationNumber);
		
		JLabel label = new JLabel("i");
		label.setFont(new Font("Tahoma", Font.PLAIN, 15));
		label.setBounds(10, 392, 13, 25);
		pnlSecant.add(label);
		
		sIterationSlider = new JSlider(JSlider.HORIZONTAL, 1, ITERATIONS, 1);
		sIterationSlider.setBounds(20, 392, 403, 23);
		sIterationSlider.setMinorTickSpacing(1);
		sIterationSlider.setSnapToTicks(true);
		sIterationSlider.setPaintTicks(true);
		pnlSecant.add(sIterationSlider);
	}
	
	// RF TABLE
	public void setRFTable(DefaultTableModel model) {
		tblRFTable = new JTable();
		tblRFTable.setModel(model);
		scrRFTable.setViewportView(tblRFTable);
		pnlRegulaFalsi.validate();
	}
	
	// SM TABLE 
	public void setSMTable(DefaultTableModel model) {
		tblSTable = new JTable();
		tblSTable.setModel(model);
		scrSTable.setViewportView(tblSTable);
		pnlSecant.validate();
	}
	

	public JTextField getTxtIterations() {
		return txtIterations;
	}

	public void setTxtIterations(JTextField txtIterations) {
		this.txtIterations = txtIterations;
	}

	public JTextField getTxtTolerance() {
		return txtTolerance;
	}

	public void setTxtTolerance(JTextField txtTolerance) {
		this.txtTolerance = txtTolerance;
	}

	public int getIterations(){
		int iterations = 0;
		try{
			iterations = Integer.parseInt(txtIterations.getText());
		}catch(Exception e){
		}
		return iterations;
	}
	
	public double getTolerance(){
		double tolerance = 0.0;
		try{
			tolerance = Double.parseDouble(txtTolerance.getText());
		}
		catch(Exception e){
		}
		return tolerance;
	}
	
	public int getStartInterval(){
		int start = 0;
		try{
			start = Integer.parseInt(txtStart.getText());
		}
		catch(Exception e){
		}
		return start;
	}
	
	public int getEndInterval(){
		int end = 0;
		try{
			end = Integer.parseInt(txtEnd.getText());
		}
		catch(Exception e){
		}
		return end;
	}
	
	public int getX1(){
		int x = 0;
		try{
			x = Integer.parseInt(txtX1.getText());
		}
		catch(Exception e){
		}
		return x;
	}
	
	public int getX2(){
		int x = 0;
		try{
			x = Integer.parseInt(txtX2.getText());
		}
		catch(Exception e){
		}
		return x;
	}
	
	
	public JTextField getTxtPolynomial() {
		return txtPolynomial;
	}

	public void setTxtPolynomial(JTextField txtPolynomial) {
		this.txtPolynomial = txtPolynomial;
	}

	public JTextField getTxtEnd() {
		return txtEnd;
	}

	public void setTxtEnd(JTextField txtEnd) {
		this.txtEnd = txtEnd;
	}

	public JTextField getTxtStart() {
		return txtStart;
	}

	public void setTxtStart(JTextField txtStart) {
		this.txtStart = txtStart;
	}

	public JTextField getTxtX1() {
		return txtX1;
	}

	public void setTxtX1(JTextField txtX1) {
		this.txtX1 = txtX1;
	}

	public JTextField getTxtX2() {
		return txtX2;
	}

	public void setTxtX2(JTextField txtX2) {
		this.txtX2 = txtX2;
	}

	public JTable getTblRFTable() {
		return tblRFTable;
	}

	public void setTblRFTable(JTable tblRFTable) {
		this.tblRFTable = tblRFTable;
	}

	public JTable getTblSTable() {
		return tblSTable;
	}

	public void setTblSTable(JTable tblSTable) {
		this.tblSTable = tblSTable;
	}

	public DefaultTableModel getTblRFTableModel() {
		return tblRFTableModel;
	}

	public void setTblRFTableModel(DefaultTableModel tblRFTableModel) {
		tblRFTable.setModel(tblRFTableModel);
		pnlRegulaFalsi.validate();
	}

	public JScrollPane getScrRFTable() {
		return scrRFTable;
	}

	public void setScrRFTable(JScrollPane scrRFTable) {
		this.scrRFTable = scrRFTable;
	}

	public JScrollPane getScrRFGraph() {
		return scrRFGraph;
	}

	public void setScrRFGraph(JScrollPane scrRFGraph) {
		this.scrRFGraph = scrRFGraph;
	}

	public JScrollPane getScrSGraph() {
		return scrSGraph;
	}

	public void setScrSGraph(JScrollPane scrSGraph) {
		this.scrSGraph = scrSGraph;
	}

	public JScrollPane getScrSTable() {
		return scrSTable;
	}

	public void setScrSTable(JScrollPane scrSTable) {
		this.scrSTable = scrSTable;
	}

	public JLayeredPane getPnlRegulaFalsi() {
		return pnlRegulaFalsi;
	}

	public void setPnlRegulaFalsi(JLayeredPane pnlRegulaFalsi) {
		this.pnlRegulaFalsi = pnlRegulaFalsi;
	}

	public JLayeredPane getPnlSecant() {
		return pnlSecant;
	}

	public void setPnlSecant(JLayeredPane pnlSecant) {
		this.pnlSecant = pnlSecant;
	}

	public JLayeredPane getPnlPolynomial() {
		return pnlPolynomial;
	}

	public void setPnlPolynomial(JLayeredPane pnlPolynomial) {
		this.pnlPolynomial = pnlPolynomial;
	}
	
	
	public int getRsIterationNumber() {
		int iteration = 0;
		try{
			iteration = Integer.parseInt(rfIterationNumber.getText());
		}
		catch(Exception e){
		}
		return iteration;
	}

	public void setRsIterationNumber(int rsIterationNumber) {
		this.rfIterationNumber.setText(""+rsIterationNumber);
	}

	public int getsIterationNumber() {
		int iteration = 0;
		try{
			iteration = Integer.parseInt(sIterationNumber.getText());
		}
		catch(Exception e){
		}
		return iteration;
	}

	public void setsIterationNumber(int sIterationNumber) {
		this.sIterationNumber.setText(""+sIterationNumber);
	}

	public JSlider getRsIterationSlider() {
		return rfIterationSlider;
	}

	public void setRsIterationSlider(JSlider rsIterationSlider) {
		this.rfIterationSlider = rsIterationSlider;
	}

	public JSlider getsIterationSlider() {
		return sIterationSlider;
	}

	public void setsIterationSlider(JSlider sIterationSlider) {
		this.sIterationSlider = sIterationSlider;
	}

	public DefaultTableModel getTblSTableModel() {
		return tblSTableModel;
	}

	public void setTblSTableModel(DefaultTableModel tblSTableModel) {
		tblSTable.setModel(tblSTableModel);
		pnlSecant.validate();
	}

	public ChartPanel getRfChartPanel() {
		return rfChartPanel;
	}

	public void setRfChartPanel(ChartPanel rfChartPanel) {
		this.rfChartPanel = rfChartPanel;
	}

	public ChartPanel getsChartPanel() {
		return sChartPanel;
	}

	public void setsChartPanel(ChartPanel sChartPanel) {
		this.sChartPanel = sChartPanel;
	}

	public XYPlot getsXYPlot() {
		return sXYPlot;
	}

	public void setsXYPlot(XYPlot sXYPlot) {
		this.sXYPlot = sXYPlot;
	}

	public XYPlot getRfXYPlot() {
		return rfXYPlot;
	}

	public void setRfXYPlot(XYPlot rfXYPlot) {
		this.rfXYPlot = rfXYPlot;
	}

	//Accepts XYSeriesCollection and title. =))
	private JFreeChart createLineChart(XYSeriesCollection dataset, String title) {
		final JFreeChart chart = ChartFactory.createXYLineChart(title, "x", "y", dataset, PlotOrientation.VERTICAL, false, false, false);
		
		return chart;
	}
	
	//Unused
	/*public void setSecantChart(XYSeriesCollection dataset) {
		ChartPanel secantChartPanel = new ChartPanel(createLineChart(
				dataset, "Secant"));
		scrSGraph.setViewportView(secantChartPanel);
		secantChartPanel.setPreferredSize(new Dimension(430, 350));
		
	}
	
	//Unused
	public void setRegulaFalsiChart(XYSeriesCollection dataset) {
		ChartPanel regulaFalsiChartPanel = new ChartPanel(createLineChart(
				dataset, "Regula Falsi"));
		scrSGraph.setViewportView(regulaFalsiChartPanel);
		regulaFalsiChartPanel.setPreferredSize(new Dimension(430, 350));
	}*/
	
	//=========================================
	//This is how you sorta create XYSeriesCollection
	//
	//	XYSeries series = new XYSeries("Series Name");
	//		series.add(x, y);
	//		series.add(x, y);
	//	
	//	XYSeriesCollection collection = new XYSeriesCollection(series);
	//=========================================
	
	//index is 0 for the graph of the polynomial
	//index is 1 for the iterations
	public void setRegulaFalsiGraphSeries(int index, XYSeriesCollection xySeries) {
		rfXYPlot.setDataset(index, xySeries);
		rfXYPlot.setRenderer(1, new XYLineAndShapeRenderer());
		rfXYPlot.getRendererForDataset(rfXYPlot.getDataset(1)).setSeriesPaint(1, Color.BLUE);
	}

	public XYSeriesCollection getRfGraphDataset() {
		return rfGraphDataset;
	}	
	
	//index is 0 for polynomial
	//index is 1 for the iterations
	public void setSecantGraphSeries(int index, XYSeriesCollection xySeries) {
		sXYPlot.setDataset(index, xySeries);
		sXYPlot.setRenderer(1, new XYLineAndShapeRenderer());
		sXYPlot.getRendererForDataset(sXYPlot.getDataset(1)).setSeriesPaint(1, Color.BLUE);
		
	}
	
	public XYSeriesCollection getsGraphDataset() {
		return sGraphDataset;
	}
}
